package com.norther.official.config;

import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.ejb.HibernatePersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * 
 * @author sean
 * 
 */
@Configuration
@ComponentScan("com.norther.official.core")
@EnableJpaRepositories(basePackages = "com.norther.official.core.dao", repositoryImplementationPostfix = "Repository")
@PropertySource(value = { "classpath:appConfig.properties" })
@EnableTransactionManagement
public class AppConfig {

	private static final String ENTITYMANAGER_PACKAGES_TO_SCAN = "com.norther.official.core.entity";

	@Autowired
	private Environment env;

	/**
	 * 创建数据源<br >
	 * 加载驱动、数据库用户名、密码。此处也可以使用其它的连接池数据源。
	 * 
	 * @return
	 */
	@Bean
	public DataSource dataSource() {
		DataSource ds = null;
		if (env.getProperty("is_h2", Boolean.class) == true) {
			ds = new EmbeddedDatabaseBuilder()
					.addScript("classpath:sql/table_2.sql")
					.addScript("classpath:sql/province_city_district_3.sql")
					.addScript("classpath:sql/data_4.sql")
					.setType(EmbeddedDatabaseType.H2).build();
		} else {
			// c3p0 数据源
			ComboPooledDataSource dataSource = new ComboPooledDataSource();
			Resource resource = new ClassPathResource("/jdbc.properties");
			try {
				Properties properties = PropertiesLoaderUtils
						.loadProperties(resource);
				dataSource.setProperties(properties);
			} catch (Exception e) {
				throw new RuntimeException("create dataSource error", e);
			}
			ds = dataSource;
		}

		return ds;
	}

	/**
	 * 相当于spring 集成 hibernate中的sessionFactory<br >
	 * 加载数据源，以及要扫描的实体包
	 * 
	 * @return
	 */
	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
		LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
		entityManagerFactory.setDataSource(dataSource());
		entityManagerFactory
				.setPersistenceProviderClass(HibernatePersistence.class);
		entityManagerFactory.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
		entityManagerFactory.setJpaProperties(hibernateProperties());

		return entityManagerFactory;
	}

	/**
	 * Jpa 实现的事务管理
	 * 
	 * @return
	 */
	@Bean
	public JpaTransactionManager transactionManager() {
		JpaTransactionManager transactionManager = new JpaTransactionManager();
		transactionManager.setEntityManagerFactory(entityManagerFactory()
				.getObject());

		return transactionManager;
	}

	/**
	 * hibernate 属性配置
	 * 
	 * @return
	 */
	private Properties hibernateProperties() {
		Properties properties = null;
		try {
			Resource resource = new ClassPathResource(
					"/hibernate-config.properties");
			properties = PropertiesLoaderUtils.loadProperties(resource);
		} catch (IOException e) {
			throw new RuntimeException("create hibernate properties error", e);
		}

		return properties;
	}
}
